﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Excel = Microsoft.Office.Interop.Excel;

namespace ExcelReport
{
    // writes the lun's priority in selected time slices
    class LunPriorityReport
    {
        object misValue;
        Excel.Application excelApp;
        Excel.Workbook workbook;

        public LunPriorityReport()
        {
            misValue = System.Reflection.Missing.Value;
            excelApp = new Excel.Application();
            // Make the object visible.
            excelApp.Visible = true;
            workbook = excelApp.Workbooks.Add(1);
        }

        /* file will be:
         * time
         * Group 1
         * lunID    priority
         * Group 2
         * lunID    priority
         * Group 3
         * lunID    priority
         * 
         * time
        */
        public void PriorityReport(double rangeSize)
        {
            //reading from file
            using (StreamReader sr = new StreamReader("../../../DataBase/OutputFiles/LunPriority.txt"))
            {
                List<int> times = new List<int>();
                String line;
                char[] delimiters = new char[] { '\t' };

                while (((line = sr.ReadLine()) != null) && ((line.CompareTo("\n")) != 0) && ((line.CompareTo("")) != 0))
                {
                    times.Add(Convert.ToInt32(line));
                    if (Convert.ToInt32(line) == 3600)
                    {
                        rangeSize = 10;
                    }
                    else if (Convert.ToInt32(line) == 32400)
                    {
                        rangeSize = 1000;
                    }
                    else if (Convert.ToInt32(line) == 43200)
                    {
                        rangeSize = 10000;
                    }
                    
                    Dictionary<int, double> group1 = new Dictionary<int, double>();
                    Dictionary<int, double> group2 = new Dictionary<int, double>();
                    Dictionary<int, double> group3 = new Dictionary<int, double>();
                    line = sr.ReadLine();
                    int groupNum = 1;
                    double maxPrio = 0.0;
                    while ((((line = sr.ReadLine()).CompareTo("\n"))!=0) && ((line.CompareTo(""))!=0))
                    {
                        if (line.Contains("Group"))
                            groupNum++;
                        else
                        {
                            String[] parts = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                            switch (groupNum)
                            {
                                case 1:
                                    if (maxPrio<Convert.ToDouble(parts[1]))
                                        maxPrio=Convert.ToDouble(parts[1]);
                                    group1.Add(Convert.ToInt16(parts[0]), Convert.ToDouble(parts[1]));
                                    break;
                                case 2:
                                    if (maxPrio<Convert.ToDouble(parts[1]))
                                        maxPrio=Convert.ToDouble(parts[1]);
                                    group2.Add(Convert.ToInt16(parts[0]), Convert.ToDouble(parts[1]));
                                    break;
                                case 3:
                                    if (maxPrio<Convert.ToDouble(parts[1]))
                                        maxPrio=Convert.ToDouble(parts[1]);
                                    group3.Add(Convert.ToInt16(parts[0]), Convert.ToDouble(parts[1]));
                                    break;
                            }
                        }
                    }
                    long ranges = (long)Math.Ceiling((maxPrio) / rangeSize);
                    Dictionary<long, int> group1Ranges = new Dictionary<long, int>();
                    Dictionary<long, int> group2Ranges = new Dictionary<long, int>();
                    Dictionary<long, int> group3Ranges = new Dictionary<long, int>();
                    long rangeNum = 0;
                    foreach (KeyValuePair<int, double> lun in group1)
                    {
                        rangeNum = (long)Math.Ceiling((lun.Value + 1) / rangeSize);
                        if (group1Ranges.ContainsKey(rangeNum))
                            group1Ranges[rangeNum]++;
                        else
                            group1Ranges.Add(rangeNum, 1);
                    }
                    foreach (KeyValuePair<int, double> lun in group2)
                    {
                        rangeNum = (long)Math.Ceiling((lun.Value + 1) / rangeSize);
                        if (group2Ranges.ContainsKey(rangeNum))
                            group2Ranges[rangeNum]++;
                        else
                            group2Ranges.Add(rangeNum, 1);
                    }
                    foreach (KeyValuePair<int, double> lun in group3)
                    {
                        rangeNum = (long)Math.Ceiling((lun.Value + 1) / rangeSize);
                        if (group3Ranges.ContainsKey(rangeNum))
                            group3Ranges[rangeNum]++;
                        else
                            group3Ranges.Add(rangeNum, 1);
                    }

                    if (((times.ElementAt(times.Count - 1)) % 36000 == 0) || (times.ElementAt(times.Count - 1) == 3600) || (times.ElementAt(times.Count - 1) == 10800))
                    {
                        try
                        {
                            Excel.Worksheet worksheet = (Excel.Worksheet)this.excelApp.Worksheets.Add(misValue, misValue, misValue, misValue);
                            worksheet = (Excel.Worksheet)workbook.ActiveSheet;
                            worksheet.Name = "Lun Priority time " + Convert.ToString(times.ElementAt(times.Count-1));
                            Dictionary<long, int> rangesDic = new Dictionary<long, int>();    // for each range - its index
                            int index=1;
                            worksheet.Cells[1, 1] = "Ranges";
                            worksheet.Cells[1, 2] = "Group 1";
                            worksheet.Cells[1, 3] = "Group 2";
                            worksheet.Cells[1, 4] = "Group 3";
                            for (long i = 0; i <= ranges; i++)
                            {
                                if (group1Ranges.ContainsKey(i + 1) || group2Ranges.ContainsKey(i + 1) || group3Ranges.ContainsKey(i + 1))
                                {
                                    rangesDic.Add(i + 1, index);
                                    worksheet.Cells[index + 1, 1] = (Convert.ToString(i * rangeSize) + "-" + Convert.ToString(((i + 1) * rangeSize)-1));
                                    index++;
                                }
                            }
                            //writing group 1
                            foreach (KeyValuePair<long, int> lun in group1Ranges)
                            {
                                worksheet.Cells[rangesDic[lun.Key]+1, 2] = lun.Value;
                            }
                            //writing group 2
                            foreach (KeyValuePair<long, int> lun in group2Ranges)
                            {
                                worksheet.Cells[rangesDic[lun.Key]+1, 3] = lun.Value;
                            }
                            //writing group 3
                            foreach (KeyValuePair<long, int> lun in group3Ranges)
                            {
                                worksheet.Cells[rangesDic[lun.Key]+1, 4] = lun.Value;
                            }

                            Excel.Range dataRange = worksheet.get_Range("A1", "D"+Convert.ToString(index));
                            Excel.ChartObjects chartObjects = (Excel.ChartObjects)(worksheet.ChartObjects(misValue));
                            Excel.ChartObject newChartObject = chartObjects.Add(200, 30, 700, 375);
                            newChartObject.Chart.ChartWizard(dataRange, Excel.XlChartType.xlColumnClustered, misValue, Excel.XlRowCol.xlColumns, 1, 1, true, "Lun Priority", "Priorities", "Amounts", misValue);
                        
                            dump(worksheet);

                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("exception " + e);
                            Environment.Exit(-1);
                        }
                    }
                }
            }
        }

        private void dump(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                Console.WriteLine(ex);
                Environment.Exit(-1);
            }
            finally
            {
                GC.Collect();
            }
        }
    }
}
